﻿namespace fpsrpg
{
    using System;
    using System.Collections.Generic;
    using System.Text;

    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Storage;

    public class Bullet2
    {
        #region Fields

        public string ImpactSound;
        public Player owner;

        bool alive;
        Rectangle bulletRectangle;
        Color[] bulletTextureData;
        Matrix BulletTransform;
        Vector2 center;
        int index;
        Vector2 position;
        float rotation;
        float scale;
        Texture2D texture;
        Vector2 velocity;

        #endregion Fields

        #region Constructors

        public Bullet2(Texture2D texture)
        {
            this.texture = texture;

            position = Vector2.Zero;
            center = new Vector2(texture.Width /2, texture.Height /2);
            velocity = Vector2.Zero;
            Rotation = 0.0f;
            Scale = 0.5f;
            alive = false;
            index = 0;
        }

        #endregion Constructors

        #region Properties

        public bool Alive
        {
            get { return alive; }
        }

        public Rectangle BulletRectangle
        {
            get { return bulletRectangle; }
            set { bulletRectangle = value; }
        }

        public Color[] BulletTextureData
        {
            get { return bulletTextureData; }
            set { bulletTextureData = value; }
        }

        public Vector2 Center
        {
            get { return center; }
        }

        public int Index
        {
            get { return index; }
            set { index = value; }
        }

        public Vector2 Position
        {
            get { return position; }
            set { position = value; }
        }

        public float Rotation
        {
            get { return rotation; }
            set
            {
                rotation = value;
                if (rotation < -MathHelper.TwoPi)
                    rotation = MathHelper.TwoPi;
                if (rotation > MathHelper.TwoPi)
                    rotation = -MathHelper.TwoPi;
            }
        }

        public float Scale
        {
            get { return scale; }
            set { scale = value; }
        }

        public Texture2D Texture
        {
            get { return texture; }
            set { texture = value; }
        }

        public Vector2 Velocity
        {
            get { return velocity; }
            set { velocity = value; }
        }

        #endregion Properties

        #region Methods

        public void Create()
        {
            alive = true;
        }

        public void Kill()
        {
            alive = false;
        }

        #endregion Methods
    }

    public class Bullets
    {
        #region Fields

        public List<Bullet2> bullets = new List<Bullet2>();

        Matrix BulletTransform;
        bool return_value;

        #endregion Fields

        #region Constructors

        public Bullets()
        {
        }

        #endregion Constructors

        #region Methods

        public void Draw(SpriteBatch spriteBatch)
        {
            foreach (Bullet2 b in bullets)
            {
                if (b.Alive)
                    spriteBatch.Draw(b.Texture, b.Position, null, Color.White, b.Rotation, b.Center, b.Scale, SpriteEffects.None, 1.0f);
            }
        }

        public void FireBullet(Player PlayerThatShoots, SoundBank TheSoundBank, String TheWeaponSound)
        {
            Bullet2 newBullet = new Bullet2(Program.gameinstance.Content.Load<Texture2D>(PlayerThatShoots.GetBulletTexture()));

            float random = 0.0f;
            random = (float)Randomizer.NextNormal() / 40;

            newBullet.Velocity = new Vector2((float)Math.Cos(PlayerThatShoots.Rotation + random), (float)Math.Sin(PlayerThatShoots.Rotation + random)) * 50.0f;

            newBullet.Position = new Vector2(PlayerThatShoots.Position.X, PlayerThatShoots.Position.Y) + newBullet.Velocity * 1.0f; //*1.75f
            newBullet.Rotation = PlayerThatShoots.Rotation + random;
            newBullet.owner = PlayerThatShoots;
            newBullet.Scale = 1.0f;
            newBullet.ImpactSound = PlayerThatShoots.GetBulletImpactSound();
            newBullet.BulletTextureData = new Color[newBullet.Texture.Width * newBullet.Texture.Height];
            newBullet.Texture.GetData(newBullet.BulletTextureData);
            newBullet.Create();
            bullets.Add(newBullet);
            TheSoundBank.PlayCue(TheWeaponSound);
        }

        public bool UpdateBullets(Sprite EnemyToCheckCollisionWith, Rectangle EnemyCollisionRectangle, Color[] texturedata, Matrix enemytransform, int TheScreenWidth, int TheScreenHeight, SoundBank TheSoundBank, ContentManager TheContentManager, out Unit hitting_owner)
        {
            hitting_owner = null;
            foreach (Bullet2 b in bullets)
            {
                b.Position += b.Velocity;
                if (b.Position.X < 0)
                    b.Kill();
                else if (b.Position.Y < 0)
                    b.Kill();
                else if (b.Position.X > TheScreenWidth)
                    b.Kill();
                else if (b.Position.Y > TheScreenHeight)
                    b.Kill();
            }

            for (int i = 0; i < bullets.Count; i++)
            {
                return_value = false;
                // Build the block's transform
                BulletTransform =
                    Matrix.CreateTranslation(new Vector3(-new Vector2(bullets[i].Texture.Width / 2, bullets[i].Texture.Height / 2), 0.0f)) *
                    Matrix.CreateRotationZ(bullets[i].Rotation) *
                    Matrix.CreateTranslation(new Vector3(bullets[i].Position, 0.0f));

                // Calculate the bounding rectangle of this block in world space
                bullets[i].BulletRectangle = Sprite.CalculateBoundingRectangle(new Rectangle(0, 0, bullets[i].Texture.Width, bullets[i].Texture.Height), BulletTransform);

                // The per-pixel check is expensive, so check the bounding rectangles
                // first to prevent testing pixels when collisions are impossible.
                if ((EnemyToCheckCollisionWith != bullets[i].owner) && EnemyCollisionRectangle.Intersects(bullets[i].BulletRectangle))
                {
                    // Check collision with person
                    if (Collision.IntersectPixels(
                        enemytransform, EnemyToCheckCollisionWith.Size.Width, EnemyToCheckCollisionWith.Size.Height, texturedata,
                        BulletTransform, bullets[i].Texture.Width, bullets[i].Texture.Height, bullets[i].BulletTextureData))
                    {
                        return_value = true;
                        if (bullets[i].ImpactSound != null)
                            TheSoundBank.PlayCue(bullets[i].ImpactSound);
                        hitting_owner = bullets[i].owner;

                        bullets.RemoveAt(i);

                    }
                    else
                        return_value = false;
                }
            }
            return return_value;
        }

        #endregion Methods
    }
}